package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.mongo.MovementApi;
import com.tanhua.dubbo.mongo.VisitorsApi;
import com.tanhua.model.domain.User;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.exception.ErrorResult;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MovementsService {

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private CommentApi commentApi;

    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VisitorsApi visitorsApi;


    /**
     * 发布动态
     *
     * @param movement
     * @param imageContent
     */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1、判断发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //2、获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3、将文件内容上传到阿里云OSS，获取请求地址
//        List<String> collect = Arrays.stream(imageContent).map(item -> {
//            try {
//                return ossTemplate.upload(item.getOriginalFilename(), item.getInputStream());
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            return null;
//        }).collect(Collectors.toList());
        List<String> urls = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            urls.add(url);
        }
        //4、将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(urls);
        //5、调用API完成发布动态
        movementApi.publish(movement);
    }

    /**
     * 查询个人动态
     *
     * @param userId
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        //1、根据用户id，调用API查询个人动态内容（PageResult  -- Movement）
//        userId = 106l;
        PageResult pr = movementApi.findByUserId(userId, page, pagesize);
        //2、获取PageResult中的item列表对象
        List<Movement> items = (List<Movement>) pr.getItems();
        //3、非空判断
        if (items == null) {
            return pr;
        }
        //4、循环数据列表
        //5、一个Movement构建一个Vo对象
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> vos = items.stream()
                .map((item) -> {
                    MovementsVo vo = MovementsVo.init(userInfo, item);
                    List<Integer> commentType = commentApi.getComment(item.getId(), UserHolder.getUserId());
                    for (Integer integer : commentType) {
                        if (integer == 1) {
                            vo.setHasLiked(1);
                        }
                    }
                    return vo;
                }).collect(Collectors.toList());
        //6、构建返回值
        pr.setItems(vos);
        return pr;
    }

    /**
     * 查询好友动态
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult movements(Integer page, Integer pagesize) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //调用api查询好友动态详情数据
        List<Movement> movementList = movementApi.findFriendMovements(userId, page, pagesize);
        log.info("好友动态数据{}", movementList);
        //当没有动态数据时返回空数组
        if (CollUtil.isEmpty(movementList)) {
            return new PageResult();
        }
        //获取动态发布人id
        List<Long> collect = movementList.stream()
                .map(item -> item.getUserId())
                .collect(Collectors.toList());
        List<MovementsVo> movementsVoList = getMovementsVos(movementList, collect);
        return new PageResult(page, pagesize, 0, movementsVoList);
    }

    /**
     * 批量查询用户动态并封装vo信息
     *
     * @param movementList
     * @param collect
     * @return
     */
    private List<MovementsVo> getMovementsVos(List<Movement> movementList, List<Long> collect) {
        //调用api查询动态发布人信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(collect, null);
        log.info("页面数据{}", map);
        //获取喜欢和心动的信息
        //根据动态信息改变
        //构造vo对象
        List<MovementsVo> movementsVoList = movementList.stream().map((movement) -> {
            UserInfo userInfo = map.get(movement.getUserId());
            MovementsVo movementsVo = MovementsVo.init(userInfo, movement);
            List<Integer> commentType = commentApi.getComment(movement.getId(), UserHolder.getUserId());
            for (Integer integer : commentType) {
                if (integer == 1) {
                    movementsVo.setHasLiked(1);
                }
                if (integer == 3) {
                    movementsVo.setHasLoved(1);
                }
            }
            return movementsVo;
        }).collect(Collectors.toList());
        log.info("页面数据{}", movementsVoList);
        return movementsVoList;
    }

    /**
     * 页面推荐动态
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        //生成推荐好友的key
        String redisKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        //获取redis存储的推荐用户id
        String redisData = this.redisTemplate.opsForValue().get(redisKey);
        List<Movement> list = Collections.EMPTY_LIST;

        if (StringUtils.isEmpty(redisData)) {
            //redis中没有推荐动态， 随机动态
            list = movementApi.randomMovements(pagesize);
        } else {
            String[] split = redisData.split(",");
            if ((page - 1) * pagesize > split.length) {
                return new PageResult();
            }
            //通过page，pagesize分页
            List<Long> pids = Arrays.stream(split)
                    .skip((page - 1) * pagesize)
                    .limit(pagesize)
                    .map(e -> Convert.toLong(e))
                    .collect(Collectors.toList());
            //redis推荐动态中有信息，
            list = movementApi.findByPids(pids);
        }
        //解析用户id
        List<Long> userIds = list.stream()
                .map(item -> item.getUserId())
                .collect(Collectors.toList());
        List<MovementsVo> movementsVos = getMovementsVos(list, userIds);
        //封装vo
        return new PageResult(page, pagesize, 0, movementsVos);
    }

    /**
     * 查询单个动态
     *
     * @param movementId
     * @return
     */
    public MovementsVo findMovementById(String movementId) {
        Movement movement = movementApi.findById(movementId);
        if (movement == null) {
            return null;
        } else {
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            return MovementsVo.init(userInfo, movement);
        }
    }

    /**
     * 查询谁看过我
     *
     * @return
     */
    public List<VisitorsVo> queryVisitorsList() {
        User user = UserHolder.get();
        List<Visitors> visitorsList = visitorsApi.queryMyVisitor(user.getId()/*UserHolder.getUserId()*/);
        if (CollUtil.isEmpty(visitorsList)) {
            return Collections.emptyList();
        }
        List<Long> collect = visitorsList.stream().map(item -> item.getVisitorUserId()).collect(Collectors.toList());
        //查询用户详细信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(collect, null);
        log.info("*************************************访客详细信息{}",map.toString());
        //封装用户信息
        VisitorsVo visitorsVo=new VisitorsVo();
        List<VisitorsVo> visitorsVoList = new ArrayList<>();
        for (Visitors visitors : visitorsList) {

            //每个访客的详细信息，
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
//            VisitorsVo visitorsVo = BeanUtil.toBeanIgnoreError(userInfo, VisitorsVo.class);
           if(userInfo!=null) {
               visitorsVo = VisitorsVo.init(userInfo, visitors);
               visitorsVoList.add(visitorsVo);
           }}
        log.info("************************************访客详细信息{}",visitorsVoList.toString());
        return visitorsVoList;
    }
}